package inner;

/**
 * 类的成员之五：内部类
 * 将一个类A定义在另一个类B里面，里面的那个类A就称为内部类(InnerClass)，
 * 类B则称为外部类(OuterClass)
 * 必要性：
 * 当一个事物A的内部，还有一个部分需要一个完整的结构B进行描述，
 * 而这个内部的完整的结构B又只为外部事物A提供服务，不在其他地方单独使用，那么整个内部的完整结构B最好使用内部类。
 * 遵循 “高内聚，低耦合” 的面向对象开发原则。
 * > 内部类的分类：
 * --成员内部类：静态的成员内部类、非静态的成员内部类
 * --局部内部类：声明在方法内、构造器内、代码块内的内部类。
 * -->（非）匿名的局部内部类
 * <p>
 * 成员内部类的理解
 * > 从类的角度看：
 * --内部可以声明属性、方法、构造器、代码块、内部类等结构
 * --此内部类可以声明父类，可以实现接口
 * --可以使用 final 修饰
 * --可以使用 abstract 修饰
 * > 从外部类的成员的角度看：
 * --在内部可以调用外部类的结构。比如：属性、方法等
 * --可以用4种权限修饰符进行修饰。
 * --可以使用 static 进行修饰
 */
public class InnerTest {
    public static void main(String[] args) {
        // 1.创建 Person 的静态的成员内部类的实例
        Person.Bird bird = new Person.Bird();
        bird.eat();
        // 2.创建 Person 的非静态的成员内部类的实例
        Person person = new Person();
        Person.Dog dog = person.new Dog();
        dog.eat();
        dog.show("斑斑");
    }

    // 局部内部类的使用
    public static void method1() {
        // 局部内部类
        class A {
            // 可以声明属性、方法等

        }
    }

    public Comparable getInstance() {
        // 提供了实现了Comparable接口的类
        // 方式1：提供了实现了Comparable接口的实现类的匿名对象
//        class MyComparable implements Comparable{
//            @Override
//            public int compareTo(Object o) {
//                return 0;
//            }
//        }

//        return new MyComparable();

        // 方式2：// 方式1：提供了实现了Comparable接口的匿名实现类的匿名对象
        return new Comparable(){

            @Override
            public int compareTo(Object o) {
                return 0;
            }
        };
    }

}

class Person {
    String name = "Tom";
    int age;

    class Dog {
        String name = "旺财";

        public void eat() {
            System.out.println("狗吃骨头");
        }

        public void show(String name) {
            System.out.println("age = " + age);
            System.out.println("name = " + this.name);
            System.out.println("name = " + name);
            System.out.println(Person.this.name);
        }
    }

    static class Bird {
        String name;

        public void eat() {
            System.out.println("鸟吃虫子");
        }
    }
}
